﻿using System;
using System.Linq;
using System.Threading.Tasks;
using HengTong.Model;
using HengTong.Model._Admin;
using HengTong.Model.Db.Hr;
using HengTong.Model.Db.Hr.Bill;
using HengTong.Model.Db.System;
using HengTong.ViewModel._Admin.SysUserJobPositionVms;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Models;

namespace HengTong.ViewModel.Hr.SysHrJobAssignmentRequestBillEntryVms;

public partial class SysHrJobAssignmentRequestBillEntryBatchVm
{
    /// <summary>
    /// 批量分配公司、部门、岗位
    /// </summary>
    /// <param name="orgId">公司ID，可选</param>
    /// <param name="groupId">部门ID，可选</param>
    /// <param name="jobPositionId">岗位ID，可选</param>
    /// <returns>操作结果</returns>
    /// <summary>
    /// 统一批量分配公司\部门\岗位
    /// Hr 模式：仅更新子表；Dept 模式：更新子表并同步人员档案与账号信息
    /// </summary>
    public async Task<Result<int>> BatchAssignPositionsAsync(
        Guid? orgId, Guid? groupId, Guid? jobPositionId, bool syncUserAccount)
    {
        var logger = Wtm.ServiceProvider.GetRequiredService<ILogger<SysHrJobAssignmentRequestBillEntryBatchVm>>();

        if (Ids == null || !Ids.Any())
            return new Result<int>("请选择需要分配的岗位申请明细");

        if (!orgId.HasValue && !groupId.HasValue && !jobPositionId.HasValue)
            return new Result<int>("请至少选择一个分配项（公司、部门或岗位）");

        var ids = Ids.Select(Guid.Parse).ToList();
        var modeLabel = syncUserAccount ? "Dept" : "Hr";
        logger.LogInformation("批量分配开始，明细数量：{Count}，模式：{Mode}", ids.Count, modeLabel);

        await using var transaction = await DC.Database.BeginTransactionAsync();
        try
        {
            // 1) 读取子表明细
            var entries = await DC.Set<SysHrJobAssignmentRequestBillEntry>()
                .Where(e => ids.Contains(e.ID))
                .ToListAsync();

            if (!entries.Any())
                return new Result<int>("未找到有效的岗位申请明细");

            var now = DateTime.Now;
            var currentUser = Wtm.LoginUserInfo?.ITCode ?? "workflow";
            int updateCount = 0;

            // 2) 批量更新子表 公司/部门/岗位
            foreach (var entry in entries)
            {
                bool hasUpdate = false;

                if (orgId.HasValue && entry.OrgId != orgId.Value)
                {
                    entry.OrgId = orgId.Value;
                    hasUpdate = true;
                }

                if (groupId.HasValue && entry.GroupId != groupId.Value)
                {
                    entry.GroupId = groupId.Value;
                    hasUpdate = true;
                }

                if (jobPositionId.HasValue && entry.JobPositionId != jobPositionId.Value)
                {
                    entry.JobPositionId = jobPositionId.Value;
                    hasUpdate = true;
                }

                if (hasUpdate)
                {
                    entry.UpdateTime = now;
                    entry.UpdateBy = currentUser;
                    updateCount++;
                }
            }

            if (updateCount == 0)
                return new Result<int>("没有需要更新的记录");

            await DC.SaveChangesAsync();

            // 3) 部门模式需要：同步人员档案与账号岗位、所属组与用户缓存
            if (syncUserAccount)
            {
                foreach (var entry in entries)
                {
                    // 人员档案
                    var targetPerson = await DC.Set<SysPerson>()
                        .Where(x => x.GetType() == typeof(SysPerson))
                        .FirstOrDefaultAsync(p => p.ID == entry.PersonId);

                    if (targetPerson == null)
                    {
                        logger.LogError("未找到ID为 {PersonId} 的人员档案，终止批量分配", entry.PersonId);
                        throw new Exception($"未找到ID为 {entry.PersonId} 的人员档案");
                    }

                    // 用子表值覆盖人员信息
                    targetPerson.OrgId = entry.OrgId;
                    targetPerson.GroupId = entry.GroupId;
                    targetPerson.JobPositionId = entry.JobPositionId;
                    targetPerson.State = PersonState.试用期;
                    targetPerson.UpdateTime = now;
                    targetPerson.UpdateBy = currentUser;

                    DC.Set<SysPerson>().Update(targetPerson);

                    // 账号与岗位
                    var user = await DC.Set<FrameworkUser>()
                        .FirstOrDefaultAsync(u => u.PersonId == targetPerson.ID);

                    if (user != null && entry.JobPositionId.HasValue)
                    {
                        // 清空旧岗位
                        await DC.Set<SysUserJobPosition>()
                            .Where(e => e.UserId == user.ID)
                            .ExecuteDeleteAsync();

                        // 添加新岗位
                        await DC.Set<SysUserJobPosition>().AddAsync(new SysUserJobPosition
                        {
                            UserId = user.ID,
                            JobPositionId = entry.JobPositionId.Value
                        });
                        await DC.SaveChangesAsync();

                        // 同步用户所属组
                        var jobPositionVm = new SysUserJobPositionVm { DC = this.DC, Wtm = this.Wtm };
                        await jobPositionVm.UpdateUserGroupAsync(user.ID);

                        // 刷新用户缓存
                        await Wtm.RemoveUserCache(user.ITCode);
                    }
                    else if (user == null)
                    {
                        logger.LogWarning("未找到工号为 {StaffNo} 的用户账号，跳过账号更新", targetPerson.StaffNo);
                    }
                }
            }

            await DC.SaveChangesAsync();
            await transaction.CommitAsync();

            logger.LogInformation("批量分配完成，模式：{Mode}，更新明细数量：{Count}", modeLabel, updateCount);

            var msg = syncUserAccount
                ? $"批量分配成功，共更新 {updateCount} 条明细，并已同步人员与账号信息"
                : $"批量分配成功，共更新 {updateCount} 条明细（未同步人员与账号信息）";

            return new Result<int> { Data = updateCount, Message = msg };
        }
        catch (Exception ex)
        {
            await transaction.RollbackAsync();
            logger.LogError(ex, "批量分配失败，模式：{Mode}", modeLabel);
            return new Result<int>($"批量分配失败：{ex.Message}");
        }
    }

    public async Task<Result<int>> DeptBatchAssignPositionsAsync(Guid? orgId, Guid? groupId, Guid? jobPositionId)
    {
        var logger = Wtm.ServiceProvider.GetRequiredService<ILogger<SysHrJobAssignmentRequestBillEntryBatchVm>>();

        if (Ids == null || !Ids.Any())
        {
            return new Result<int>("请选择需要分配的岗位申请明细");
        }

        if (!orgId.HasValue && !groupId.HasValue && !jobPositionId.HasValue)
        {
            return new Result<int>("请至少选择一个分配项（公司、部门或岗位）");
        }

        var ids = Ids.Select(Guid.Parse).ToList();
        logger.LogInformation("准备部门批量分岗位，明细数量：{Count}", ids.Count);

        await using var transaction = await DC.Database.BeginTransactionAsync();
        try
        {
            // 1. 取子表明细
            var entries = await DC.Set<SysHrJobAssignmentRequestBillEntry>()
                .Where(e => ids.Contains(e.ID))
                .ToListAsync();

            if (!entries.Any())
            {
                return new Result<int>("未找到有效的岗位申请明细");
            }

            var currentTime = DateTime.Now;
            var currentUser = Wtm.LoginUserInfo?.ITCode ?? "workflow";
            int updateCount = 0;

            // 2. 先更新子表字段（公司/部门/岗位）
            foreach (var entry in entries)
            {
                bool hasUpdate = false;

                if (orgId.HasValue && entry.OrgId != orgId.Value)
                {
                    entry.OrgId = orgId.Value;
                    hasUpdate = true;
                }

                if (groupId.HasValue && entry.GroupId != groupId.Value)
                {
                    entry.GroupId = groupId.Value;
                    hasUpdate = true;
                }

                if (jobPositionId.HasValue && entry.JobPositionId != jobPositionId.Value)
                {
                    entry.JobPositionId = jobPositionId.Value;
                    hasUpdate = true;
                }

                if (hasUpdate)
                {
                    entry.UpdateTime = currentTime;
                    entry.UpdateBy = currentUser;
                    updateCount++;
                }
            }

            if (updateCount > 0)
            {
                await DC.SaveChangesAsync();
            }

            // 3. 基于子表，同步人员档案与账号岗位、组、缓存
            foreach (var entry in entries)
            {
                // 人员档案
                var targetPerson = await DC.Set<SysPerson>()
                    .Where(x => x.GetType() == typeof(SysPerson))
                    .FirstOrDefaultAsync(p => p.ID == entry.PersonId);

                if (targetPerson == null)
                {
                    logger.LogError("未找到ID为 {PersonId} 的人员档案，终止批量分配", entry.PersonId);
                    throw new Exception($"未找到ID为 {entry.PersonId} 的人员档案");
                }

                // 用子表值覆盖人员信息
                targetPerson.OrgId = entry.OrgId;
                targetPerson.GroupId = entry.GroupId;
                targetPerson.JobPositionId = entry.JobPositionId;
                targetPerson.State = PersonState.试用期;
                targetPerson.UpdateTime = DateTime.Now;
                targetPerson.UpdateBy = currentUser;

                DC.Set<SysPerson>().Update(targetPerson);

                // 账号与岗位
                var user = await DC.Set<FrameworkUser>()
                    .FirstOrDefaultAsync(u => u.PersonId == targetPerson.ID);

                if (user != null)
                {
                    // 添加新岗位（有值才写入）
                    if (entry.JobPositionId.HasValue)
                    {
                        // 清空旧岗位
                        await DC.Set<SysUserJobPosition>()
                            .Where(e => e.UserId == user.ID)
                            .ExecuteDeleteAsync();

                        await DC.Set<SysUserJobPosition>().AddAsync(new SysUserJobPosition
                        {
                            UserId = user.ID,
                            JobPositionId = entry.JobPositionId.Value
                        });

                        await DC.SaveChangesAsync();


                        // 同步用户所属组
                        var jobPositionVm = new SysUserJobPositionVm
                        {
                            DC = this.DC,
                            Wtm = this.Wtm
                        };
                        await jobPositionVm.UpdateUserGroupAsync(user.ID);

                        // 刷新用户缓存
                        await Wtm.RemoveUserCache(user.ITCode);
                    }
                }
                else
                {
                    logger.LogWarning("未找到工号为 {StaffNo} 的用户账号，跳过账号更新", targetPerson.StaffNo);
                }
            }

            await DC.SaveChangesAsync();
            await transaction.CommitAsync();

            logger.LogInformation("部门批量分岗位成功，更新明细数量：{Count}", updateCount);

            return new Result<int>
            {
                Data = updateCount,
                Message = $"批量分配成功，共更新 {updateCount} 条明细，并已同步人员与账号信息"
            };
        }
        catch (Exception ex)
        {
            await transaction.RollbackAsync();
            logger.LogError(ex, "部门批量分岗位失败");
            return new Result<int>($"批量分配失败：{ex.Message}");
        }
    }
}